var express = require("express");
var router = express.Router();
var {
  academyModel,
  stageModel,
  questionModel,
  paperModel,
  adminModel,
  clazzModel,
  dispositionModel,
  resultModel,
} = require("../model/model");

router.get("/add", async (req, res) => {
  // let arr = [
  //   {name:'人工智能学院'},
  //   {name:'文化传媒学院'},
  //   {name:'云计算学院'},
  //   {name:'大数据学院'},
  //   {name:'鸿蒙开发学院'}
  // ]
  // academyModel.create(arr);
  // let arr = [
  //   {name:'人工专高一',academy:'66d017fb24d07183da965f7d'},
  //   {name:'传媒专高一',academy:'66d017fb24d07183da965f7e'},
  //   {name:'鸿蒙专高二',academy:'66d017fb24d07183da965f81'},
  //   {name:'云计算转高三',academy:'66d017fb24d07183da965f7f'}
  // ]
  // await stageModel.create(arr);
  // let arr = [
  //   {title:'说说你对react diff的理解？',cate:4,belong:'66d01b681c9b3a7e402cc853',difficulty:2,
  //   // options:[
  //   //   {content:'生成器函数',isRight:true},
  //   //   {content:'普通函数',isRight:false},
  //   //   {content:'异步函数',isRight:false},
  //   //   {content:'生成器函数',isRight:true},
  //   // ],
  //   answer:'react diff算法是一种用于比较虚拟DOM树和实际DOM树的算法，它通过比较两个树的不同来更新实际DOM树。这种算法可以减少不必要的DOM操作，提高性能。'},
  //   {title:'react是一个基于JavaScript的前端流行框架',cate:4,belong:'66d01b681c9b3a7e402cc853',difficulty:1,
  //   // options:[
  //   //   {content:'普通函数',isRight:false},
  //   //   {content:'函数嵌套函数',isRight:true},
  //   //   {content:'异步函数',isRight:false},
  //   //   {content:'生成器函数',isRight:true},
  //   // ],
  //   answer:'React 是由 Facebook 开发的一个 JavaScript 库，用于构建用户界面，特别是单页应用的视图层。它专注于视图的渲染和组件化，并且提供了一个灵活的机制来处理 UI 的状态和数据流。'},
  // ]
  // questionModel.create(arr);
  // let arr = [
  //   {name:'人工智能2024年八月底李政豪出的卷',time:[1724918400,1724925600],pass_score:60,out:100,creator:'66d02419a5ff158b2695e15f',
  //   questions:['66d01e7204cff809066638d6','66d01e7204cff809066638db','66d02033e55fdecbd5b40167','66d02033e55fdecbd5b40166'],
  //   type:1},
  //   {name:'人工智能2024年八月底李政豪出的卷',time:[1724918400,1724925600],pass_score:60,out:100,creator:'66d02419a5ff158b2695e15f',
  //   questions:[],
  //   type:0},
  // ]
  // paperModel.create(arr);
  let arr = [
    { name: "2311A班", stage: "66d01b681c9b3a7e402cc853" },
    { name: "2311B班", stage: "66d01b681c9b3a7e402cc853" },
    { name: "2310A班", stage: "66d01b681c9b3a7e402cc855" },
    { name: "2310B班", stage: "66d01b681c9b3a7e402cc855" },
    { name: "2312A班", stage: "66d529cc2f40666dedf0f35f" },
    { name: "2312B班", stage: "66d529cc2f40666dedf0f35f" },
  ];
  clazzModel.create(arr);
  res.send();
});

router.post('/deletemany',async(req,res)=>{
  let {ids} = req.body;
  await resultModel.deleteMany({paper:{$in:ids}});
  await dispositionModel.deleteMany({pid:{$in:ids}});
  await paperModel.deleteMany({_id:{$in:ids}});
  res.send();
})

router.post('/deleteone',async(req,res)=>{
  let {_id} = req.body;
  await paperModel.deleteOne({_id});
  await dispositionModel.deleteMany({pid:_id});
  await resultModel.deleteMany({paper:_id});
  res.send({code:200});
})

router.get("/getlist", async (req, res) => {
  let { page, cate, flag, creator, str, pagesize } = req.query;
  let query = {};
  if (cate) query.belong = cate;
  if (flag != "0") {
    flag = Number(flag);
    let now = Date.now();
    if (flag <= 3 && flag != 0) {
      query.flag = flag;
    } else {
      switch (flag) {
        case 4:
          // 查询当前时间大于开始时间并且小于结束时间
          query = {
            "time.0": { $lt: now },
            "time.1": { $gt: now },
          };
          break;
        case 5:
          // 查询当前时间大于结束时间
          query = {
            "time.1": { $lt: now },
          };
          break;
        case 6:
          // 查询当前时间小于开始时间
          query = {
            "time.0": { $gt: now },
          };
          break;
        default:
          // 如果没有匹配的 flag，可以设置一个空的查询或者抛出错误
          query = {};
          break;
      }
    }
  }
  if (creator) query.creator = creator;
  if (str) query.name = new RegExp(str);
  // console.log(query);
  let data = await paperModel
    .find(query)
    .skip((page - 1) * pagesize)
    .limit(Number(pagesize))
    .populate("belong")
    .populate("creator");
  data = await processData(data);
  let total = await paperModel.countDocuments(query);

  res.send({ data, code: 200,total });
});
async function processData(data) {
  // 使用 Promise.all 来确保所有异步操作都完成
  const processedData = await Promise.all(data.map(async item => {
    if (!item.type) {
      // 等待 dispositionModel.findOne 的结果
      let { radio, checkbox, short, judgment } = await dispositionModel.findOne({ pid: item._id });
      // 更新 item.questions.length
      item.questions.length = (radio.count || 0) + (checkbox.count || 0) + (short.count || 0) + (judgment.count || 0);
    }
    // 返回处理后的 item
    return item;
  }));

  // 返回最终结果
  return processedData;
}

router.get("/getcate", async (req, res) => {
  let data = await stageModel.find();
  res.send({ data, code: 200 });
});

router.get("/getlecturer", async (req, res) => {
  let data = await adminModel.find({ role: "讲师" });
  res.send({ data, code: 200 });
});

router.post("/update", async (req, res) => {
  let { _id, flag } = req.body;
  let obj = await paperModel.findOne({ _id });
  let now = Date.now();
  if (obj.time[1] < now) return res.send({ code: 400, msg: "考试时间已过" });
  await paperModel.updateOne({ _id }, { $set: { flag } });
  res.send({ code: 200, msg: "修改成功" });
});

router.get("/gettopic", async (req, res) => {
  let { page, pagesize, _id } = req.query;
  let questions = await questionModel
    .find({ belong: _id,status:1 })
    .skip((page - 1) * pagesize)
    .limit(Number(pagesize));
  let totalTopic = await questionModel.find({belong:_id,status:1 });
  let total = totalTopic.length;
  let stages = await stageModel.find();
  let arr = stages.map((item) => {
    return {
      label: item.name,
      value: item._id,
    };
  });
  arr.unshift({
    label: "全选",
    checkAll: true,
  });
  res.send({ code: 200, arr, questions,total });
});

router.post("/getradiocount", async (req, res) => {
  let { radio } = req.body;
  let data = await questionModel.find({ belong: { $in: radio }, cate: 1 });
  res.send({ length: data.length, code: 200 });
});

router.post("/getoptionscount", async (req, res) => {
  let { options } = req.body;
  let data = await questionModel.find({ belong: { $in: options }, cate: 2 });
  res.send({ length: data.length, code: 200 });
});

router.post("/getjudgmentcount", async (req, res) => {
  let { judgment } = req.body;
  let data = await questionModel.find({ belong: { $in: judgment }, cate: 3 });
  res.send({ length: data.length, code: 200 });
});
router.post("/getshortcount", async (req, res) => {
  let { short } = req.body;
  let data = await questionModel.find({ belong: { $in: short }, cate: 4 });
  res.send({ length: data.length, code: 200 });
});

router.get("/getclazz", async (req, res) => {
  const academies = await academyModel.find({}).exec();

  // Initialize the result array
  const tree = [];

  for (const academy of academies) {
    // Fetch all stages for the current academy
    const stages = await stageModel.find({ academy: academy._id }).exec();

    const academyNode = {
      label: academy.name,
      value: academy._id,
      children: [],
    };

    for (const stage of stages) {
      // Fetch all classes for the current stage
      const classes = await clazzModel.find({ stage: stage._id }).exec();

      const stageNode = {
        label: stage.name,
        value: stage._id,
        children: [],
      };

      for (const clazz of classes) {
        const clazzNode = {
          label: clazz.name,
          value: clazz._id,
        };
        stageNode.children.push(clazzNode);
      }

      if (stageNode.children.length > 0) {
        academyNode.children.push(stageNode);
      }
    }
    if (academyNode.children.length > 0) {
      tree.push(academyNode);
    }
  }
  res.send({ tree, code: 200 });
});

router.post("/addexam", async (req, res) => {
  const { exam, topic, data,_id } = req.body;
  console.log(req.body,'req.body------------');
  let obj = {};
  if (!exam.type) {
    let out =
      Number(topic.radio.fraction) * Number(topic.radio.num) +
      Number(topic.options.fraction) * Number(topic.options.num) +
      Number(topic.judgment.fraction) * Number(topic.judgment.num) +
      Number(topic.short.fraction) * Number(topic.short.num);
    obj.out = out;
    obj.questions = [];

  } else {
    let out = data.reduce((sum, item) => sum + Number(item.score), 0);
    obj.out = out;
    obj.questions = data.map((item) => item._id);
  }
  if (exam.pass == "1") {
    obj.pass_score = obj.out * Number(exam.percentage / 100);
  } else {
    obj.pass_score = Number(exam.passScore);
  }
  obj.class = exam.class;
  obj.publishTime = exam.publishTime;
  obj.name = exam.name;
  obj.creator = exam.creator;
  obj.time = exam.time.map((item) => {
    return new Date(item).getTime();
  });
  obj.flag = 1;
  obj.type = exam.type;
  obj.belong = exam.belong;
  let newobj = {};
  if(_id){
    await paperModel.updateOne({_id},{$set:obj})
  }else{
    newobj = await paperModel.create(obj);
  }
  let { radio, options, judgment, short } = topic;
  if (newobj.type) {
    newobj.questions.length =
      Number(radio.num) +
      Number(options.num) +
      Number(judgment.num) +
      Number(short.num);
    await paperModel.updateOne(
      { _id: newobj._id },
      { $set: { questions: newobj.questions } }
    );
  }
  if(!exam.type){
    let mapQuestions = {
      pid: newobj._id,
      radio: { arr: radio.range, count: Number(radio.num),fraction:Number(radio.fraction),judgment:Number(radio.judgment) },
      checkbox: { arr: options.range, count: Number(options.num),fraction:Number(options.fraction),judgment:Number(options.judgment) },
      judgment: { arr: judgment.range, count: Number(judgment.num),fraction:Number(judgment.fraction),judgment:Number(judgment.judgment) },
      short: { arr: short.range, count: Number(short.num),fraction:Number(short.fraction),judgment:Number(short.judgment) },
    };
    if(_id){
      console.log(mapQuestions);
      await dispositionModel.updateOne({pid:_id},{$set:mapQuestions})
    }else{
      await dispositionModel.create(mapQuestions);
    }
  }
  if (newobj) {
    res.send({ code: 200 });
  } else {
    res.send({ code: 500 });
  }
});

router.get("/getpaper", async (req, res) => {
  let { _id } = req.query;
  let paper = await paperModel.findOne({ _id });
  let obj = {};
  let exam = {};
  let length = {};
  if (!paper.type) {
    let disposition = await dispositionModel.findOne({ pid: _id });
    let { radio, checkbox, judgment, short } = disposition;
    let radioLength = await questionModel.find({cate:1});
    let checkboxLength = await questionModel.find({cate:2});
    let judgmentLength = await questionModel.find({cate:3});
    let shortLength = await questionModel.find({cate:4});
    length = {
      radio: radioLength.length,
      options: checkboxLength.length,
      judgment: judgmentLength.length,
      short: shortLength.length,
    }
    obj.radio = {
      range: radio.arr,
      num: radio.count,
      judgment: radio.judgment,
      fraction: radio.fraction,
    };
    obj.options = {
      range: checkbox.arr,
      num: checkbox.count,
      judgment: checkbox.judgment,
      fraction: checkbox.fraction,
    };
    obj.judgment = {
      range: judgment.arr,
      num: judgment.count,
      judgment: judgment.judgment,
      fraction: judgment.fraction,
    };
    obj.short = {
      range: short.arr,
      num: short.count,
      judgment: short.judgment,
      fraction: short.fraction,
    };
  }
  let { questions, out, name, time, pass_score, type, belong, publishTime } =
    paper;
  const result = pass_score / out;
  const scaledResult = Math.floor(result * 100); // 将结果乘以100并取整
  if (scaledResult % 10 === 0) {
    exam.pass = "1";
    exam.percentage = scaledResult;
  } else {
    exam.pass = "0";
    exam.passScore = pass_score;
  }
  let average = '';
  if(paper.type) average = out / questions.length;
  exam = {
    name,
    time,
    type,
    publishTime,
    class: paper.class,
    belong,
    ...exam,
    flag:paper.flag
  };
  res.send({
    code: 200,
    obj,
    exam,
    length,
    questions,
    average
  });
});

module.exports = router;
